// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.specialist.service.impl;

import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.enums.ButlerBusinessTypeEnum;
import com.liuxinlong.modules.dao.ButlerTrainDao;
import com.liuxinlong.modules.dao.DifficultyDao;
import com.liuxinlong.modules.dao.DifficultyPlanDao;
import com.liuxinlong.modules.dao.ExpertDao;
import com.liuxinlong.modules.dao.ExpertProjectDao;
import com.liuxinlong.modules.dao.ProjectNewsDao;
import com.liuxinlong.modules.dao.RoleDao;
import com.liuxinlong.modules.dao.UserRoleRelationDao;
import com.liuxinlong.modules.entity.ButlerTrain;
import com.liuxinlong.modules.entity.Difficulty;
import com.liuxinlong.modules.entity.Expert;
import com.liuxinlong.modules.entity.ExpertProject;
import com.liuxinlong.modules.entity.ProjectNews;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.entity.UserRole;
import com.liuxinlong.modules.entity.UserRoleRelation;
import com.liuxinlong.modules.specialist.service.SpreadService;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 专家组工作首页信息服务层实现类
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2023年4月3日
 */
@Slf4j
@Service
public class SpreadServiceImpl implements SpreadService {

    @Autowired
    private ExpertProjectDao projectDao;

    @Autowired
    private ButlerTrainDao butlerTrainDao;

    @Autowired
    private DifficultyDao difficultyDao;

    @Autowired
    private ProjectNewsDao projectNewsDao;

    @Autowired
    private ExpertDao expertDao;

    @Autowired
    private DifficultyPlanDao difficultyPlanDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private UserRoleRelationDao userRoleRelationDao;

    @Override
    public Map<String, Object> querySpreadInfo() {
        Map<String, Object> dataMap = new HashMap<>();
        Map<String, Object> workMap = new HashMap<>();

        // 项目统计
        String summaryTime = TimeUtils.getCurrentYearStart();
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("summaryTime", summaryTime);
        Map<String, Object> summaryMap = projectDao.queryProjectSummary(queryParam);
        dataMap.put("planTotal", summaryMap.get("totalNum"));
        dataMap.put("pendingNum", summaryMap.get("pendingNum"));
        dataMap.put("finishNum", summaryMap.get("finishNum"));

        // 课程统计
        Map<String, Object> query = new HashMap<>();
        query.put("status", 1);
        query.put("summaryTime", summaryTime);
//        query.put("businessType", ButlerBusinessTypeEnum.EXPERT.getValue());
        int classNum = butlerTrainDao.getTrainInfoCount(query);
        dataMap.put("classNum", classNum);

        // 获取全部专家信息map
        Map<String, Map<String, String>> expertMap = expertDao.getExpertMap();

        // 统计入项专家数
        Set<String> joinExpertSet = new HashSet<>();
        List<ExpertProject> projectList = projectDao.getProjectList();
        Set<String> joinPorjectSet = new HashSet<>();
        for (ExpertProject project : projectList) {
            if (StringUtils.isEmpty(project.getAppointedExpert()) && StringUtils.isEmpty(project.getDivideExpert())) {
                continue;
            }
            if (project.getStatus() == 4) {
                continue;
            }
            joinPorjectSet.add(project.getId());
            List<String> expList = new ArrayList<>();
            expList.addAll(Arrays.asList(project.getAppointedExpert().split(",")));
            expList.addAll(Arrays.asList(project.getDivideExpert().split(",")));
            for (String exp : expList) {
                joinExpertSet.add(exp);
            }
        }

        // 统计知识分享专家数
        query.put("startNum", 0);
        query.put("pageSize", 10000);
        int joinClassNum = 0;
        Set<String> joinClassExpertSet = new HashSet<>();
        List<ButlerTrain> classList = butlerTrainDao.queryTrainListByParam(query);
        for (ButlerTrain classInfo : classList) {
            boolean joinFlag = false;
            if (StringUtils.isEmpty(classInfo.getShareUser())) {
                continue;
            }
            List<String> classExpertList = Arrays.asList(classInfo.getShareUser().split(","));
            for (String exp : classExpertList) {
                if (expertMap.containsKey(exp)) {
                    joinFlag = true;
                    joinClassExpertSet.add(exp);
                }
            }
            if (joinFlag) {
                joinClassNum++;
            }
        }

        // 专家工作参与率
        Map<String, Object> workRate = new HashMap<>();
//        int joinProjectRate = ObjectUtils.isEmpty(projectList) ? 0 : joinPorjectSet.size() * 100 / projectList.size();
        int joinNum = 0;
        for (String expertStr : joinExpertSet) {
            if (!expertMap.containsKey(expertStr)) {
                continue;
            }
            joinNum++;
        }
        int joinProjectExpertRate = ObjectUtils.isEmpty(expertMap) ? 0 : joinNum * 100 / expertMap.size();
        workRate.put("project", joinProjectExpertRate);
        int joinClassExpertRate = ObjectUtils.isEmpty(expertMap) ? 0 : joinClassExpertSet.size() * 100 / expertMap.size();
        workRate.put("knowledge", joinClassExpertRate);
        dataMap.put("workRate", workRate);

        // 项目参与率
        Map<String, Object> projectRate = new HashMap<>();
//        int joinNum = 0;
//        for(String expertStr : joinExpertSet) {
//            if(!expertMap.containsKey(expertStr)) {
//                continue;
//            }
//            joinNum++;
//        }
//        int joinProjectExpertRate = ObjectUtils.isEmpty(expertMap) ? 0 : joinNum * 100 / expertMap.size();
        projectRate.put("join", joinProjectExpertRate);
        projectRate.put("not", 100 - joinProjectExpertRate);
        dataMap.put("projectRate", projectRate);

        // 风险点
        Map<String, Object> queryDifParam = new HashMap<>();
        queryDifParam.put("startNum", 0);
        queryDifParam.put("pageSize", 10000);
        queryDifParam.put("pointType", 2);
        int riskNum = difficultyDao.getDifficultyCount(queryDifParam);

        // 解决方案
//        Map<String, Object> queryPlanParam = new HashMap<>();
        int expertPlanNum = difficultyPlanDao.getEffectiveDifficultyPlanCount();

        // 专家工作汇总
        Map<String, Object> workSummary = new HashMap<>();
        workSummary.put("class", joinClassNum);
        workSummary.put("solve", expertPlanNum);
        workSummary.put("risk", riskNum);
        dataMap.put("workSummary", workSummary);

        // 知识分享
        Map<String, Object> shareInfo = new HashMap<>();
        Map<String, Object> queryShareParam = new HashMap<>();
        queryShareParam.put("status", 1);
//        queryShareParam.put("businessType", ButlerBusinessTypeEnum.EXPERT.getValue());
        String currentYear = TimeUtils.getYear();
        queryShareParam.put("startTime", currentYear + "-01-01");
        Map<String, Map<String, Object>> expertClassMap = butlerTrainDao.getCountByMonth(queryShareParam);
        shareInfo.put("one", expertClassMap.containsKey(currentYear + "-01") ? expertClassMap.get(currentYear + "-01").get("count") : 0);
        shareInfo.put("two", expertClassMap.containsKey(currentYear + "-02") ? expertClassMap.get(currentYear + "-02").get("count") : 0);
        shareInfo.put("three", expertClassMap.containsKey(currentYear + "-03") ? expertClassMap.get(currentYear + "-03").get("count") : 0);
        shareInfo.put("four", expertClassMap.containsKey(currentYear + "-04") ? expertClassMap.get(currentYear + "-04").get("count") : 0);
        shareInfo.put("five", expertClassMap.containsKey(currentYear + "-05") ? expertClassMap.get(currentYear + "-05").get("count") : 0);
        shareInfo.put("six", expertClassMap.containsKey(currentYear + "-06") ? expertClassMap.get(currentYear + "-06").get("count") : 0);
        shareInfo.put("seven", expertClassMap.containsKey(currentYear + "-07") ? expertClassMap.get(currentYear + "-07").get("count") : 0);
        shareInfo.put("eight", expertClassMap.containsKey(currentYear + "-08") ? expertClassMap.get(currentYear + "-08").get("count") : 0);
        shareInfo.put("nine", expertClassMap.containsKey(currentYear + "-09") ? expertClassMap.get(currentYear + "-09").get("count") : 0);
        shareInfo.put("ten", expertClassMap.containsKey(currentYear + "-10") ? expertClassMap.get(currentYear + "-10").get("count") : 0);
        shareInfo.put("eleven", expertClassMap.containsKey(currentYear + "-11") ? expertClassMap.get(currentYear + "-11").get("count") : 0);
        shareInfo.put("twelve", expertClassMap.containsKey(currentYear + "-12") ? expertClassMap.get(currentYear + "-12").get("count") : 0);
        dataMap.put("shareInfo", shareInfo);

        dataMap.put("workMap", workMap);
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        List<UserRoleRelation> userRoleRelationList = userRoleRelationDao.queryRelationByUserId(currentUser.getId());
        UserRole highRole = roleDao.getRoleBySn("J016");
        List<UserRoleRelation> existHighList;
        if (ObjectUtils.isEmpty(highRole)) {
            existHighList = new ArrayList<>();
        } else {
            existHighList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), highRole.getId())).collect(Collectors.toList());
        }
        dataMap.put("highPermission", !existHighList.isEmpty());

        UserRole manageRole = roleDao.getRoleBySn("J017");
        List<UserRoleRelation> existList;
        if (ObjectUtils.isEmpty(manageRole)) {
            existList = new ArrayList<>();
        } else {
            existList = userRoleRelationList.stream().filter(relation -> StringUtils.equals(relation.getRoleId(), manageRole.getId())).collect(Collectors.toList());
        }
        dataMap.put("managePermission", !existList.isEmpty());

        return dataMap;
    }

    @Override
    public List<Map<String, Object>> queryTrendsList(Map<String, Object> queryParam) {
        List<ProjectNews> projectNewsList = projectNewsDao.pageProjectNewsList(queryParam);
        List<Map<String, Object>> dataList = new ArrayList<>(projectNewsList.size());
        for (ProjectNews projectNews : projectNewsList) {
            Map<String, Object> item = ObjectUtils.object2Map(projectNews);
            dataList.add(item);
        }
        return dataList;
    }

    @Override
    public int getTrendsCount(Map<String, Object> queryParam) {
        return projectNewsDao.getProjectNewsCount(queryParam);
    }

    @Override
    public Map<String, Object> queryRankingInfo(Map<String, Object> queryParam) {
        Map<String, Object> dataMap = new HashMap<>();
        int topNum = 3;
        List<Expert> contributionRankingList = expertDao.queryContributionList(topNum);
        dataMap.put("contributionRankingList", contributionRankingList);

        queryParam.put("pointType", 1);
        queryParam.put("status", 3);
        List<Difficulty> difficultyList = difficultyDao.pageDifficultyList(queryParam);
        List<Map<String, Object>> overList = new ArrayList<>(difficultyList.size());
        if (!ObjectUtils.isEmpty(difficultyList)) {
            int sort = (int) queryParam.get("startNum") + 1;
            Map<String, Map<String, String>> projectMap = projectDao.getProjectMap();
            for (Difficulty difficulty : difficultyList) {
                Map<String, Object> item = new HashMap<>();
                item.put("sort", sort);
                if (projectMap.containsKey(difficulty.getProjectId())) {
                    item.put("projectName", projectMap.get(difficulty.getProjectId()).get("name"));
                }
                item.put("difficultyName", difficulty.getRemark());
                overList.add(item);
                sort++;
            }
        }
        dataMap.put("difficultyList", overList);
        int totalDifNum = difficultyDao.getDifficultyCount(queryParam);
        dataMap.put("totalDifNum",totalDifNum);
        return dataMap;
    }
}
